package com.solo.game.snake;

import java.awt.Point;
import java.util.ArrayList;
import java.util.List;

/**
 * 
 *  <code>GameEngine</code>
 *  <p>GameEngine描述: 游戏引擎，驱动游戏进行，每开始一次游戏，就要新启一个引擎
 *  
 *  @version 1.0 
 *  @author Zangrong.Solo 
 *  日期: Dec 13, 2012 3:13:33 PM
 */
public class GameEngine implements Runnable{

    private Snake snake;
    
    private Game game;
    
    private Bonus bonus;
    
    public GameEngine(Game game)
    {
        this.game = game;
        this.snake = game.getSnake();
        this.bonus = game.getBonus();
    }
    
    /**
     * 主线程
     */
    @Override
    public void run() {
        boolean runable = true;
        boolean eat = false;
        // 是否穿墙 true是穿，false不穿
        boolean infinite = game.getPreference().isInfinite();
        String action = game.getAction();
        int row = game.getPreference().getRow();
        int column = game.getPreference().getColumn();
        
        List<Point> eatList = new ArrayList<Point>();
        Point tailPoint = null;
        
        Point headPoint = snake.getHeadPoint();
        
        while (runable) {
            if (!Game.GAME_STATE_RUNNING.equals(game.getState())) {
                speed();
                continue;
            }
            // 获得头部坐标
            int x = headPoint.x;
            int y = headPoint.y;
            // 根据键盘动作设置头部新坐标
            action = game.getAction();
            
            // TODO 穿墙模式应该在这里处理
            if (Action.ACTION_KEY_UP.equals(action)) {
                x -= 1;
            } else if (Action.ACTION_KEY_LEFT.equals(action)) {
                y -= 1;
            } else if (Action.ACTION_KEY_RIGHT.equals(action)) {
                y += 1;
            } else if (Action.ACTION_KEY_DOWN.equals(action)) {
                x += 1;
            }
            
            if (!infinite) {
                // 如果碰到墙或自己
                if (x == row || x == -1 || y == column || y == -1
                        || game.isFieldAvailable(x, y) == false) {
                    runable = false;
                    game.setState(Game.GAME_STATE_STOP);
                    break;
                }
            }
            else {
                // TODO 穿墙模式
                
            }

            // 头部逻辑处理
            snake.processHead(x, y);

            // 尾部逻辑处理
            tailPoint = snake.processTail(x, y);
            
            // 吃到奖励
            if (bonus.isEat(x, y)) {
                bonus.createBonus();
                eatList.add(new Point(x, y));
                eat = true;
            }
            // 尾巴到达苹果点的位置(改吃法增长滞后)
            if (eat == true && tailPoint.equals(eatList.get(0))) {
                snake.addTail(game.getField(tailPoint.x, tailPoint.y));
                game.setFieldAvailable(tailPoint.x, tailPoint.y, false);
                game.setFieldColor(tailPoint.x, tailPoint.y, game.getPreference().getSnakeColor());
                eatList.remove(0);
                eat = eatList.size() == 0 ? false : true;
            }
            speed();
        }
        // TODO 积分统计
        
    }

    /**
     * 
     * <P>描述: 控制速度
     * 
     * @author Zangrong.Solo
     * 日期: Dec 19, 2012 11:58:47 AM
     */
    private void speed() {
        try {
            // 休眠时间（此时间决定蛇移动的速度） TODO 设计速度模式
            Thread.sleep(this.game.getPreference().getPeriod());
        } catch (InterruptedException e) {
            System.out.println("线程异常中断");
            e.printStackTrace();
        }
    }

}
